﻿using DFGK.WMS.Common.Result;
using DFGK.WMS.Common.Tools;
using DFGK.WMS.Common.Web;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.IRepository.IService;
using DFGK_WMS.Model;
using DFGK_WMS.Model.DTO;
using DFGK_WMS.Model.Models;
using DFGK_WMS.Repository;
using DFGK_WMS.WebAPI.Controllers.Result;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NPOI.SS.Formula.PTG;
using SqlSugar;
using System.Security.Claims;

namespace DFGK_WMS.WebAPI.Controllers.设备
{
    /// <summary>
    /// 立库
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class WCSController : ControllerBase
    {
        public ITPutawayOrderRepository TPutawayOrderService { get; set; }

        public ITCellRepository TCellRepository { get; set; }

        private readonly ISqlSugarClient _Client;

        private ITOutboundOrderDetailRepository TOutboundOrderDetail;
        //入库垛  
        private readonly IStackingStorageRepository _StackingStorage;

        private readonly IStackingStorageService _IStackStorageService;
        private readonly ILogRepository logRepository;

        private readonly DFGK_DB dbContext;
        public WCSController(
            DFGK_DB dbContext,
            ITPutawayOrderRepository tPutawayOrderRepository,
            ITOutboundOrderDetailRepository TOutboundOrderDetail,
            ITCellRepository tCellRepository,
            ISqlSugarClient client,
            IStackingStorageRepository stackingStorage,
            IStackingStorageService iStackStorageService,
            ILogRepository logRepository)
        {
            this.dbContext = dbContext;
            TPutawayOrderService = tPutawayOrderRepository;
            this.TOutboundOrderDetail = TOutboundOrderDetail;
            TCellRepository = tCellRepository;
            _Client = client;
            _StackingStorage = stackingStorage;
            _IStackStorageService = iStackStorageService;
            this.logRepository = logRepository;

        }
        /// <summary>
        /// 出入库任务状态上报
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        //[HttpPost]
        //public IActionResult TasklikuAppear(LiKuDto dto)
        //{
        //    TPutawayOrderService.AddTLogs();
        //    if (dto.method != "end")
        //    {
        //        return Ok(BaseResult.ReturnInfo(1, "", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
        //    }
        //    var order = TPutawayOrderService.Getputawayorder(x=>x.Code==dto.taskCode);
        //    //查询任务
        //    if (order == null)
        //    {
        //        return Ok(BaseResult.ReturnInfo(1, "未找到该任务", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
        //    }

        //    //入库任务
        //    if (order.SourceType == 1)
        //    {
        //        //仓位查询
        //        var cell = TCellRepository.Gettcell(order.LocationCode);
        //        if (cell == null)
        //        {
        //            return Ok(BaseResult.ReturnInfo(1, "未找到该仓位", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
        //        }
        //        //修改仓位
        //        cell.FullStatus = 1;
        //        if (!TCellRepository.UpdateCell(cell))
        //        {
        //            return Ok(BaseResult.ReturnInfo(1, "仓位修改失败", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
        //        }

        //        //任务修改
        //        order.Status = 5;
        //        if (!TPutawayOrderService.UpdatePutawayorder(order))
        //        {
        //            return Ok(BaseResult.ReturnInfo(1, "任务修改失败", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
        //        }
        //    }
        //    //出库任务
        //    else if (order.SourceType == 2)
        //    {
        //        //获取输送线巷道节点
        //        var waydata = new { taskCode = order.Code, Roadway = order.Roadway };
        //        var waydate= HttpHelper.SendPostRequestes("获取巷道节点", waydata);
        //        LogHelper.Info("获取巷道节点:" + waydate);
        //        //输送线出库
        //        var data = new { taskCode = order.Code, startPoint = waydate.data, endPoint = order.SiteCode };
        //        var lindata = HttpHelper.SendPostRequest("出库任务", data);
        //        LogHelper.Info("出库任务：" + lindata);
        //    }
        //    return Ok(BaseResult.ReturnInfo(0, "", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
        //}


        /// <summary>
        /// 出入库任务状态上报
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult TasklikuAppear(LiKuDtoV2 dto)
        {
            TPutawayOrderService.AddTLogs();
            if (dto.method != "end")
            {
                return Ok(BaseResult.ReturnInfo(1, "", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
            }
            var order = TPutawayOrderService.Getputawayorder(x => x.Code == dto.taskCode);
            //查询任务
            if (order == null)
            {
                return Ok(BaseResult.ReturnInfo(1, "未找到该任务", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
            }
            var stackingStoragesList = TPutawayOrderService.GetStackingStorage(out string msg, dto.palletBarCode);
            if (stackingStoragesList == null)
            {
                return Ok(BaseResult.ReturnInfo(1, msg, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));

            }
            string uname = HttpContext.User.FindFirstValue("UserName");
            string runame = HttpContext.User.FindFirstValue("RealName");
            int uid = Convert.ToInt32(HttpContext.User.FindFirstValue("Id"));

            //入库任务
            if (dto.SourceType == 1)
            {
                ApiBaseResult baseResult = new ApiBaseResult();
                if (string.IsNullOrEmpty(dto.palletBarCode) || string.IsNullOrEmpty(stackingStoragesList.ExpectedLocation))
                {
                    baseResult.Code = "500";
                    baseResult.Success = false;
                    baseResult.Message = "参数有误";
                    return Ok(baseResult);
                }

                var stackingStorage = _Client.Queryable<TStackingStorage>().First(s => s.Status == 1 && s.PalletBarcode == dto.palletBarCode);
                if (stackingStorage is null)
                {
                    baseResult.Code = "500";
                    baseResult.Success = false;
                    baseResult.Message = "无组垛信息";
                    return Ok(baseResult);
                }

                var cell = _Client.Queryable<TCell>().First(c => c.Code == stackingStoragesList.ExpectedLocation);
                if (cell is null)
                {
                    baseResult.Code = "500";
                    baseResult.Success = false;
                    baseResult.Message = "仓位不存在" + stackingStoragesList.ExpectedLocation;
                    return Ok(baseResult);
                }
                if (stackingStorage.ExpectedLocation != stackingStoragesList.ExpectedLocation)
                {
                    if (cell.FullStatus == 1 || cell.Status == 2 || cell.IsLock == true)
                    {
                        baseResult.Code = "500";
                        baseResult.Success = false;
                        baseResult.Message = "仓位已被占用" + stackingStoragesList.ExpectedLocation;
                        return Ok(baseResult);
                    }
                }

                var orderDetail = _Client.Queryable<TReceivingOrderDetail>().First(x => x.Id == stackingStorage.RelatedOrderDetailId);
                TStation station = _Client.Queryable<TStation>().First(r => r.WhId == orderDetail.WarehouseId);
                DFGK_WMS.Model.Models.PalletBindMaterialModel palletBindMaterialModel = new DFGK_WMS.Model.Models.PalletBindMaterialModel()
                {
                    PalletBarcode = dto.palletBarCode,
                    MaterialPackageBindModel = new DFGK_WMS.Model.Models.MaterialPackageBindModel()
                    {
                        OrderDetailId = orderDetail.Id,
                        MaterialCode = orderDetail.MaterialCode,
                        Qty = orderDetail.Qty,
                    }
                };
                string errMsg = string.Empty;
                decimal? weight = order.TotalWeight == null ? 0 : order.TotalWeight;
                var result = _IStackStorageService.ExecCreateInstruct(out errMsg, orderDetail, station, palletBindMaterialModel, stackingStoragesList.ExpectedLocation, weight);

           
                string? ip = HttpContext.Connection.RemoteIpAddress?.ToString();
                TLog logg = new TLog();
                logg.LogType = 1;
                logg.ActionType = 4;
                logg.ModuleName = "添加入库";
                logg.UserName = uname;
                logg.RealName = runame;
                logg.UserId = uid;
                logg.Description = result ? uname + "入库成功" : uname + "入库失败: " + errMsg;
                logg.Ipaddress = ip;
                logRepository.AddTLod(logg);
                if (!result)
                {
                    baseResult.Code = "500";
                    baseResult.Success = false;
                    baseResult.Message = errMsg;
                    return Ok(baseResult);
                }
                baseResult.Code = "200";
                baseResult.Success = true;
                baseResult.Message = "操作成功";
                return new JsonResult(baseResult);
            }
            //出库任务
            else if (dto.SourceType == 2)
            {
                List<string> pallList = new List<string>
                {
                    dto.palletBarCode
                };
                var list = TPutawayOrderService.GetShippingLockCells(out string message ,dto.palletBarCode);
                if(list.Count() <= 0)
                {
                    return Ok(BaseResult.Result(false, "500",message));
                }
                var orderIdNullable = list.First().OrderDetailId;
                int orderId = orderIdNullable.Value;
                decimal? outQtyDecimal = list.First().OutQty;
                int outQtyInt = (int)outQtyDecimal.Value;
                SubmitOutListDTO orderDTO = new SubmitOutListDTO(uid,uname,runame, pallList.ToArray(), orderId, outQtyInt, uid,"");
                if (orderDTO == null)
                {
                    return Ok(BaseResult.Result(false,"500", "参数传入错误！"));
                }

                using (var tran = dbContext.Database.BeginTransaction())
                {
                    try
                    {
                        bool result = false;
                        result = TOutboundOrderDetail.SubmitOutInventoryReview(orderDTO, out message);

                        if (!result)
                        {
                            //transaction.Dispose();
                            tran.Rollback();
                            return Ok(BaseResult.Result(false, "500", message));
                        }

                        if (TOutboundOrderDetail.GetStackingStorages(orderDTO.palletBarcode).Count <= 0)
                        {
                            tran.Rollback();
                            return Ok(BaseResult.Result(false,"500", "请求参数有误，请检查请求参数"));
                        }

                        //根据垛条码查询垛主
                        var item = TOutboundOrderDetail.GetStackingStacker(orderDTO.palletBarcode);
                        if (item.Count == 0)
                        {
                            //transaction.Dispose();
                            tran.Rollback();
                            return Ok(BaseResult.Result(false, "500", "该托条码对应的垛主信息有误"));
                        }

                        // 根据垛条码删除入库垛信息表中数据
                        if (!TOutboundOrderDetail.HandleUnbindOfOutstorage(orderDTO, out message))
                        {
                            //transaction.Dispose();
                            tran.Rollback();
                            return Ok(BaseResult.Result(false,"500", message));
                        }

                        // 提交事务
                        //transaction.Complete();
                        tran.Commit();
                    }
                    catch (Exception ex)
                    {
                        // 回滚事务（如果发生异常）
                        tran.Rollback();
                        //transaction.Dispose(); // 或者使用 tran.Rollback()
                        return Ok(BaseResult.Result(false, "500", ex.Message));
                    }
                    //}

                    return Ok(BaseResult.Result(true,"200", "出库解绑成功"));
                }
            }
            return Ok(BaseResult.ReturnInfo(0, "", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
        }



        /// <summary>
        /// 出入库任务
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public IActionResult TaskReceive(TaskLiku task)
        {
            var data = HttpHelper.WCSSendPostRequest("WMS/v1/CMD", task);
            LogHelper.Info("wcs出入库：" + data);
            return Ok(BaseResult.ReturnInfo(0, data, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
        }


        /// <summary>
        /// WCS传参  WMS回传仓位
        /// </summary>
        /// <param name="wcsRequest"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult WCSRequestReturn(WCSRequestDto wcsRequest)
        {
            TLog logg = new TLog();
            logg.LogType = 1;
            logg.ActionType = 4;
            
            logg.ModuleName = "扫码成功";
            logg.Description = "扫码成功";
            logRepository.AddTLod(logg);
            if (wcsRequest == null)
            {
                return Ok(BaseResult.Result(true, "请求参数为空！", "500"));
            }
            var list = TPutawayOrderService.WCSRequestReturn(wcsRequest);
            if (list == null)
            {
                return Ok(BaseResult.Result(false, "查询失败！", "500"));
            }

            //获取上架单信息
            //给堆垛机下发任务
            TaskLiku task = new TaskLiku();
            task.taskId = list.taskId;
            task.taskSubType = "101";
            task.startPositionId = "";
            task.endPositionId = list.LocationCode;
            //task.endPositionId = "B02-04-03";
            task.palletCode = list.palletCode;
            task.type = 1;
            var data = HttpHelper.WCSSendPostRequest("WMS/v1/CMD", task);
            LogHelper.Info("wcs出入库：" + data);
            if (data == "" || data == null)
            {
                return Ok(BaseResult.Result(false, "保存失败", "500"));
            }
            
            return Ok(BaseResult.Result(list, "执行成功！", "200"));
        }

        /// <summary>
        /// 推送所有设备状态
        /// </summary>
        /// <param name="wcsRequest"></param>
        /// <returns></returns>
        [HttpPost]
        public IActionResult UpdEquipment(List<TEquipment> entity)
        {
            if (entity == null)
            {
                return Ok(BaseResult.Result(true, "请求参数为空！", "200"));
            }
            var IsOk = TPutawayOrderService.UpdEquipment(out string messgae, entity);
            if (IsOk)
            {
                return Ok(BaseResult.Result(true, "更新成功！", "200"));
            }
            return Ok(BaseResult.Result(false, messgae, "500"));
        }
    }
}
